package com.danbay.framework.utils.security;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by Administrator on 2015/9/30.
 */
public class DES3Utils
{
    /*
	 * 说明：内部私钥；
	 */
    private static final String PRIVATE_KEY = "!@#$FD254tSWER@#$Eser";

    /*
	 * 定义 加密算法,可用 DES,DESede,Blowfish
	 */
    private static final String Algorithm = "DESede";

    /*
	 * 功能：3des加密
	 * 参数：
	 * 		value  	待加密字符串
	 * 		key  	原始密钥字符串
	 */
    public static String Encrypt3DES(String value)
    {
        return Encrypt3DES(value,PRIVATE_KEY);
    }
    public static String Encrypt3DES(String value, String key)
    {
        String sValue = "";
        try
        {
            sValue = byte2Base64(encryptMode(GetKeyBytes(key), value.getBytes()));
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
        return sValue;
    }

    /*
     * 功能：3des解密
     * 参数：
     * 		value  	待解密字符串
     * 		key  	原始密钥字符串
     */
    public static String Decrypt3DES(String value )
    {
        return Decrypt3DES(value,PRIVATE_KEY);
    }
    public static String Decrypt3DES(String value, String key)
    {
        String sValue = "";
        try
        {
            byte[] b = decryptMode(GetKeyBytes(key), org.apache.commons.codec.binary.Base64.decodeBase64(value));
            //byte[] b = decryptMode(GetKeyBytes(key), Base64.decode(value));
            sValue =  new String(b);
            b = null;
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
        return sValue;
    }


    /************************************************************************************************
     * 私有方法
     *************************************************************************************************/

    /*
     * 转换成base64编码
     */
    private static String byte2Base64(byte[] b)
    {
        return  Base64.encodeBase64String(b);
        //return  Base64.encode(b);
    }

    /*
     * keybyte为加密密钥，长度为24字节
     * src为被加密的数据缓冲区（源）
     */
    private static byte[] encryptMode(byte[] keybyte, byte[] src)
    {
        try {
            //生成密钥,加密
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            Cipher c1 = Cipher.getInstance(Algorithm);

            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        }
        catch (NoSuchAlgorithmException e1)
        {
            e1.printStackTrace();
        }
        catch (javax.crypto.NoSuchPaddingException e2)
        {
            e2.printStackTrace();
        }
        catch (Exception e3)
        {
            e3.printStackTrace();
        }
        return null;
    }


    /*
     * keybyte为加密密钥，长度为24字节
     * src为加密后的缓冲区
     */
    private static byte[] decryptMode(byte[] keybyte , byte[] src)
    {
        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

            //解密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        }
        catch (NoSuchAlgorithmException e1)
        {
            e1.printStackTrace();
        }
        catch (javax.crypto.NoSuchPaddingException e2)
        {
            e2.printStackTrace();
        }
        catch (Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }

    /*
	  * 计算24位长的密码byte值,首先对原始密钥做MD5算hash值，再用前8位数据对应补全后8位
	  */
    private static byte[] GetKeyBytes(String strKey) throws Exception
    {
        if (null == strKey || strKey.length() < 1)
        {
            throw new Exception("key is null or empty!");
        }

        MessageDigest alg = MessageDigest.getInstance("MD5");
        alg.update(strKey.getBytes());

        byte[] bkey = alg.digest();

        //System.out.println("md5key.length=" + bkey.length);
        //System.out.println("md5key=" + byte2hex(bkey));

        int start = bkey.length;
        byte[] bkey24 = new byte[24];
        for (int i = 0; i < start; i++)
        {
            bkey24[i] = bkey[i];
        }

        for (int i = start; i < 24; i++) {//为了与.net16位key兼容
            bkey24[i] = bkey[i - start];
        }

        //System.out.println("byte24key.length=" + bkey24.length);
        //System.out.println("byte24key=" + byte2hex(bkey24));
        return bkey24;
    }


    public   static void main(String []  args)
    {
        System.out.println("127.0.0.1   密文是："+Encrypt3DES("127.0.0.1") );
        System.out.println("admindanbay123   密文是："+Encrypt3DES("admindanbay123") );


        String host = "r-wz9fc99b79d26b44.redis.rds.aliyuncs.com";
        System.out.println( host+"  密文是："+Encrypt3DES(host) );

        String pass = "DanbayRedis2017";
        System.out.println( pass+"  密文是："+Encrypt3DES(pass) );

    }
}
